// 给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中，返回 true ；否则，返回 false 。

// 单词必须按照字母顺序，通过相邻的单元格内的字母构成，其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。



var exist = function(board, word) {
    function change(nums, wd, i, j) {
        if (word.length == wd.length) {
            return ture;
        }
        for (let i = 0; i < word.length; i++) {
            if (nums[i][j] === undefined) { continue };
            if (nums[i][j] == word.split('')[i]) {
                wd.push(nums[i][j])
            }
            change(nums, wd, i, j + 1);
            change(nums, wd, i + 1, j);
        }
    }
    change(board, [], 0, 0);
};


/**
 * @param {character[][]} board
 * @param {string} word
 * @return {boolean}
 */
var exist = function(board, word) {
    const rowNum = board.length;
    const colNum = board[0].length;

    for (let i = 0; i < rowNum; ++i) {
        for (let j = 0; j < colNum; ++j) {
            if (board[i][j] === word[0]) {
                const isExist = __exist(board, word, i, j, {});
                if (isExist) return true; // 找到就返回
            }
        }
    }
    return false;
};



/**
 * @param {character[][]} board
 * @param {string} word
 * @param {number} row
 * @param {number} col
 * @param {object} visited
 * @return {boolean}
 */
function __exist(board, word, row, col, visited) {
    // 单词中字母全部匹配，说明可以搜索到，返回true
    if (!word.length) {
        return true;
    }

    const key = `${row}-${col}`;
    // 越界、之前访问过、单词首字母和当前元素不相同，返回false
    if (
        row >= board.length ||
        row < 0 ||
        col >= board[0].length ||
        col < 0 ||
        visited[key] ||
        board[row][col] !== word[0]
    ) {
        return false;
    }

    visited[key] = true;
    word = word.slice(1);
    // 下、上、右、左搜索（顺序不重要）
    const success =
        __exist(board, word, row + 1, col, visited) ||
        __exist(board, word, row - 1, col, visited) ||
        __exist(board, word, row, col + 1, visited) ||
        __exist(board, word, row, col - 1, visited);

    // success为false时，就是回溯
    visited[key] = success;
    return success;